﻿using System;
using System.Net.NetworkInformation;

namespace Microsoft.SPOT.Net.NetworkInformation
{
    public class NetworkInterface
    {
        protected NetworkInterface(int interfaceIndex)
        {
        }

        public string[] DnsAddresses { get; private set; }
        public string GatewayAddress { get; private set; }
        public string IPAddress { get; private set; }
        public bool IsDhcpEnabled { get; private set; }
        public bool IsDynamicDnsEnabled { get; private set; }
        public NetworkInterfaceType NetworkInterfaceType { get; private set; }
        public byte[] PhysicalAddress { get; set; }
        public string SubnetMask { get; private set; }

        public void EnableDhcp()
        {
        }

        public void EnableDynamicDns()
        {
        }

        public void EnableStaticDns(string[] dnsAddresses)
        {
        }

        public void EnableStaticIP(string ipAddress, string subnetMask, string gatewayAddress)
        {
        }

        public static NetworkInterface[] GetAllNetworkInterfaces()
        {
            var result = new NetworkInterface[1];

            // take the first network interface and return local IP
            foreach (var nif in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
            {
                if (nif.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Ethernet
                    && nif.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Wireless80211)
                    continue;

                if (nif.OperationalStatus != System.Net.NetworkInformation.OperationalStatus.Up)
                    continue;

                if (!nif.Supports(System.Net.NetworkInformation.NetworkInterfaceComponent.IPv4))
                    continue;

                var properties = nif.GetIPProperties();
                var uniCastAdresses = properties.UnicastAddresses;
                if (uniCastAdresses.Count == 0)
                    continue;

                UnicastIPAddressInformation uniCastAddress = null;
                foreach (var address in uniCastAdresses)
                {
                    if (address.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        uniCastAddress = address;
                        break;
                    }
                }
                if (uniCastAddress == null)
                    continue;

                var networkInterface = new NetworkInterface(0)
                {
                    DnsAddresses = getDnsAddresses(properties),
                    GatewayAddress = properties.GatewayAddresses[0].Address.ToString(),
                    IPAddress = uniCastAddress.Address.ToString(),
                    IsDhcpEnabled = properties.GetIPv4Properties().IsDhcpEnabled,
                    IsDynamicDnsEnabled = properties.IsDynamicDnsEnabled,
                    NetworkInterfaceType = getNetworkInterfaceType(nif),
                    PhysicalAddress = getPhysicalAddress(nif),
                    SubnetMask = uniCastAddress.IPv4Mask.ToString(),

                };

                result[0] = networkInterface;
                return result;
            }
            // if no network available return null 
            return null;
        }

        private static string[] getDnsAddresses(System.Net.NetworkInformation.IPInterfaceProperties properties)
        {
            var dnsAddresses = properties.DnsAddresses;
            var result = new string[dnsAddresses.Count];
            for (int i = 0; i < dnsAddresses.Count; i++)
            {
                result[i] = dnsAddresses[i].ToString();
            }
            return result;
        }

        private static byte[] getPhysicalAddress(System.Net.NetworkInformation.NetworkInterface nif)
        {
            return nif.GetPhysicalAddress().GetAddressBytes();
        }

        private static NetworkInterfaceType getNetworkInterfaceType(System.Net.NetworkInformation.NetworkInterface nif)
        {
            switch (nif.NetworkInterfaceType)
            {
                case System.Net.NetworkInformation.NetworkInterfaceType.Ethernet:
                    return NetworkInterfaceType.Ethernet;
                case System.Net.NetworkInformation.NetworkInterfaceType.Wireless80211:
                    return NetworkInterfaceType.Wireless80211;
                case System.Net.NetworkInformation.NetworkInterfaceType.Unknown:
                    return NetworkInterfaceType.Unknown;
                default:
                    return NetworkInterfaceType.Unknown;
            }
        }

        public void ReleaseDhcpLease()
        {
        }

        public void RenewDhcpLease()
        {
        }

    }
}
